﻿using System;

using D2D = Microsoft.WindowsAPICodePack.DirectX.Direct2D1;
using DI = Microsoft.WindowsAPICodePack.DirectX.WindowsImagingComponent;
using DW = Microsoft.WindowsAPICodePack.DirectX.DirectWrite;
using Paint = System.Drawing;

namespace Framework
{
    public struct Color
    {
        private D2D.ColorF color;

        public float A { get { return color.Alpha; } set { color.Alpha = value; } }
        public float R { get { return color.Red; } set { color.Red = value; } }
        public float G { get { return color.Green; } set { color.Green = value; } }
        public float B { get { return color.Blue; } set { color.Blue = value; } }

        public D2D.ColorF GetD2D()
        {
            return color;
        }

        public int ToArgb()
        {
            return ((int)(A*255)<< 24)+((int)(R*255)<<16)+((int)(G*255)<<8 ) + ((int)(B*255));
        }

        public static readonly Color Black = Color.FromArgb(0xFF, 0x00, 0x00, 0x00);
        public static readonly Color Blue = Color.FromArgb(0xFF, 0x00, 0x00, 0xFF);
        public static readonly Color Brown = Color.FromArgb(0xFF, 0xA5, 0x2A, 0x2A);
        public static readonly Color Cyan = Color.FromArgb(0xFF, 0x00, 0xFF, 0xFF);
        public static readonly Color DarkGray = Color.FromArgb(0xFF, 0xA9, 0xA9, 0xA9);
        public static readonly Color Gray = Color.FromArgb(0xFF, 0x80, 0x80, 0x80);
        public static readonly Color Green = Color.FromArgb(0xFF, 0x00, 0x80, 0x00);
        public static readonly Color LightGray = Color.FromArgb(0xFF, 0xD3, 0xD3, 0xD3);
        public static readonly Color Magenta = Color.FromArgb(0xFF, 0xFF, 0x00, 0xFF);
        public static readonly Color Orange = Color.FromArgb(0xFF, 0xFF, 0xA5, 0x00);
        public static readonly Color Purple = Color.FromArgb(0xFF, 0x80, 0x00, 0x80);
        public static readonly Color Red = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00);
        public static readonly Color Transparent = Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF);
        public static readonly Color White = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF);
        public static readonly Color Yellow = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00);

        #region ARGB

        public static Color FromArgb(byte a, byte r, byte g, byte b)
        {
            return new Color() { A = (float)a, B = (float)b, G = (float)g, R = (float)r };
        }

        public static Color FromArgb(double a, double r, double g, double b)
        {
            return new Color() { A = (float)a, B = (float)b, G = (float)g, R = (float)r };
        }

        public static Color FromArgb(float a, float r, float g, float b)
        {
            return new Color() { A = (float)a, B = (float)b, G = (float)g, R = (float)r };
        }

        #endregion

        #region Struct

        public override int GetHashCode()
        {
            return color.GetHashCode();
        }

        public override bool Equals(object o)
        {
            return (o is Color) ? Equals(color == ((Color)o).color) : false;
        }

        public bool Equals(Color color)
        {
            return (this.color == color.color);
        }

        public override string ToString()
        {
            return color.ToString();
        }

        public static bool operator ==(Color color1, Color color2)
        {
            return (color1.color == color2.color);
        }

        public static bool operator !=(Color color1, Color color2)
        {
            return (color1.color != color2.color);
        }

        #endregion
    }

    public struct Point
    {
        public double X;
        public double Y;

        public D2D.Point2F GetD2D()
        {
            return new D2D.Point2F((float)X, (float)Y);
        }
    }

    public struct Rect
    {
        public double X, Y, Weight, Height;

        public bool Contains(Point point)
        {
            return true;
        }

        public static Rect Empty;

        public bool IsEmpty;

        public double Left
        {
            get { return X; }
        }

        public double Top
        {
            get { return Y; }
        }

        public double Right
        {
            get { return IsEmpty ? Double.NegativeInfinity : X + Weight; }
        }

        public double Bottom
        {
            get { return IsEmpty ? Double.NegativeInfinity : Y + Height; }
        }

        public void Intersect(Rect rect)
        {
        }

        public void Union(Rect rect)
        {
        }

        public void Union(Point point)
        {
        }

    }

    public struct Size
    {
        public double Height;
        public double Width;
        public bool IsEmpty;

        public static Size Empty;

        internal Size Max(Size other)
        {
            throw new NotImplementedException();
        }

        internal Size Min(Size other)
        {
            throw new NotImplementedException();
        }
    }

    public struct Thickness
    {
        public double Left;
        public double Top;
        public double Right;
        public double Bottom;
    }

    public struct CornerRadius
    {
        public double TopLeft;
        public double TopRight;
        public double BottomRight;
        public double BottomLeft;
    }

    public class Matrix : Base
    {
        static Matrix()
        {
            RegisterType(typeof(Matrix));
            RegisterProp(typeof(Matrix), "M11", typeof(Double), null);
            RegisterProp(typeof(Matrix), "M12", typeof(Double), null);
            RegisterProp(typeof(Matrix), "M21", typeof(Double), null);
            RegisterProp(typeof(Matrix), "M22", typeof(Double), null);
            RegisterProp(typeof(Matrix), "OffsetX", typeof(Double), null);
            RegisterProp(typeof(Matrix), "OffsetY", typeof(Double), null);
        }

        public bool IsIdentity { get; private set; }
        public static Matrix Identity
        {
            get {return new Matrix();}
        }

        public Point Transform(Point point)
        {
            throw new NotImplementedException();
        }
    }

    public struct Duration
    {
        public static Duration Automatic;
        public static Duration Forever;
        public bool HasTimeSpan;
        public TimeSpan TimeSpan;

        public Duration Add(Duration duration)
        {
            throw new NotImplementedException();
        }

        public static int Compare(Duration t1,Duration t2)
        {
            throw new NotImplementedException();
        }

        public static Duration Plus(Duration duration)
        {
            throw new NotImplementedException();
        }

        public Duration Subtract(Duration duration)
        {
            throw new NotImplementedException();
        }

    }

    public struct GridLength
    {
        public static GridLength Auto;
        public GridUnitType GridUnitType;
        public bool IsAbsolute;
        public bool IsAuto;
        public bool IsStar;
        public double Value;
    }

    public enum GridUnitType
    {
        Auto,Pixel,Star
    }

}
